home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
uucp.cq
/
uucp.c
Wrap
Text File
|
1985-04-27
|
18KB
|
841 lines
/* @(#)uucp.c 1.9 */
#include "uucp.h"
#include <sys/types.h>
#include <sys/stat.h>
#include "uust.h"
#include <sys/param.h>
/*
* uucp
* user id
* make a copy in spool directory
*/
int Uid;
int Copy = 0;
char Nuser[32];
char *Ropt = " ";
char Path[MAXFULLNAME], Optns[10], Ename[NAMEBUF];
char Grade = 'n';
#define MAXCOUNT 20 /* maximun number of commands per C. file */
char Sfile[MAXFULLNAME];
#define JOBON 1
#define JOBOFF 0
#ifdef ONJOB
int prjob = JOBON;
#else
int prjob = JOBOFF;
#endif
char **Env;
int notifopt;
long ulimit();
main(argc, argv, envp)
char *argv[];
char **envp;
{
int ret;
int errors = 0;
char *sysfile1, *sysfile2, *cp;
char file1[MAXFULLNAME], file2[MAXFULLNAME];
long limit, dummy;
char msg[100];
#ifdef FOWARD
char tsys2[MAXFULLNAME];
char tfile1[MAXFULLNAME];
char sys2save[MAXFULLNAME];
#endif
char sqn[5];
char *strchr(), *strcpy(), *strcat();
char *strrchr();
char *ep;
char *fopt;
fopt = NULL;
Env = envp;
if((ep = (char *)getenv("JOBNO="))){
if(strcmp("ON", ep) == SAME)
prjob = JOBON;
if(strcmp("OFF", ep) == SAME)
prjob = JOBOFF;
}
strcpy(Progname, "uucp");
Pchar = 'U';
/*
* find name of local system
*/
uucpname(Myname);
umask(WFMASK);
Optns[0] = '-';
Optns[1] = 'd';
Optns[2] = 'c';
Ename[0] = Nuser[0] = Optns[3] = '\0';
Sfile[0] = '\0';
while(argc>1 && argv[1][0] == '-'){
switch(argv[1][1]){
/*
* make a copy of the file in the spool
* directory.
*/
case 'C':
Copy = 1;
Optns[2] = 'C';
break;
/*
* not used
*/
case 'c':
break;
/*
* not used
*/
case 'd':
break;
case 'f':
Optns[1] = 'f';
break;
/*
* invok uux to execute command
*/
case 'e':
#ifdef FOWARD
sprintf(Ename, "%s", &argv[1][2]);
#else
sprintf(Ename, "%.6s", &argv[1][2]);
#endif
break;
/*
* set service grade (not used)
*/
case 'g':
Grade = argv[1][2];
break;
case 'j':
prjob = (prjob == JOBON)?JOBOFF:JOBON;
break;
/*
* send notification to local user
*/
case 'm':
strcat(Optns, "m");
if(argv[1][2] != '\0'){
fopt = &argv[1][2];
strcat(Optns, "o");
}
break;
/*
* send notification to user on remote
* if no user specified do not send notification
*/
case 'n':
notifopt++;
sprintf(Nuser, "%.8s", &argv[1][2]);
break;
/*
* create JCL files but not start uucico
*/
case 'r':
Ropt = argv[1];
break;
case 's':
Spool = &argv[1][2];
break;
/*
* turn on debugging
*/
case 'x':
Debug = atoi(&argv[1][2]);
if (Debug <= 0)
Debug = 1;
break;
default:
printf("unknown flag %s\n", argv[1]);
break;
}
--argc; argv++;
}
DEBUG(4, "\n\n** %s **\n", "START");
gwd(Wrkdir);
if(fopt){
if(*fopt != '/')
sprintf(Sfile, "%s/%s", Wrkdir, fopt);
else
sprintf(Sfile, "%s", fopt);
}
/*
* work in spool directory
*/
ret = chdir(Spool);
ASSERT(ret == 0, "CANNOT CHDIR TO SPOOL - ", Spool, ret);
if(ret != 0) {
fprintf(stderr, "No spool directory - %s - get help\n", Spool);
cleanup(-2);
}
Uid = getuid();
/*
* find id of user who spawned command to
* determine
*/
ret = guinfo(Uid, User, Path);
if(Nuser[0] == '\0')
strcpy(Nuser, User);
ASSERT(ret == 0, "CAN NOT FIND UID", "", Uid);
strcpy(Loginuser,User);
DEBUG(4, "UID %d, ", Uid);
DEBUG(4, "User %s,", User);
DEBUG(4, "Ename (%s) ", Ename);
DEBUG(4, "PATH %s\n", Path);
if (argc < 3) {
fprintf(stderr, "usage uucp from ... to\n");
cleanup(-3);
}
/*
* set up "to" system and file names
*/
if ((cp = strchr(argv[argc - 1], '!')) != NULL) {
sysfile2 = argv[argc - 1];
*cp = '\0';
if (*sysfile2 == '\0')
sysfile2 = Myname;
else
sprintf(Rmtname, "%.6s", sysfile2);
if (versys(sysfile2) != 0) {
fprintf(stderr, "bad system name: %s\n", sysfile2);
cleanup(-4);
}
strcpy(file2, cp + 1);
#ifdef FOWARD
/*
* Fowarding
*/
if ( strchr(file2, '!') != NULL && file2[0] != '~' ) {
if (chkpub(file2)==FAIL) {
fprintf(stderr,"\n Forwarding to nonpublic directories denied - uucp failed\n");
cleanup(-5);
}
*cp = '!';
strcpy(file2, cp);
*cp = '\0';
}
#endif
} else {
sysfile2 = Myname;
strcpy(file2, argv[argc - 1]);
}
/*
* if there are more than 2 argc, file2 is a directory
*/
if (argc > 3)
strcat(file2, "/");
/*
* system names limited to SYSNSIZE(6) chars
*/
if (strlen(sysfile2) > SYSNSIZE)
*(sysfile2 + SYSNSIZE) = '\0';
#ifdef FOWARD
strncpy(sys2save, sysfile2, SYSNSIZE);
#endif
/*
* do each from argument
*/
getseq(sqn);
while (argc > 2) {
if ((cp = strchr(argv[1], '!')) != NULL) {
sysfile1 = argv[1];
*cp = '\0';
if (strlen(sysfile1) > SYSNSIZE)
*(sysfile1 + SYSNSIZE) = '\0';
if (*sysfile1 == '\0')
sysfile1 = Myname;
else
sprintf(Rmtname, "%.6s", sysfile1);
if (versys(sysfile1) != 0) {
fprintf(stderr, "bad system name: %s\n", sysfile1);
cleanup(-6);
}
strcpy(file1, cp + 1);
#ifdef FOWARD
/*
* if forwarding for a file to receive
* then simulate a remote
* xuucp by prepending reverse order of
* of forwarding route to file and xeq uucp on
* remote site
*/
if (strchr(file1,'!') != NULL)
{
register char *i;
if (chkpub(file1)==FAIL) {
fprintf(stderr,"\n Forwarding from nonpublic directories denied - uucp failed\n");
cleanup(-7);
}
dlogent("sysfile2", sysfile2);
if (strncmp(sysfile2, Myname, SYSNSIZE) == SAME) {
/*
* due to remote fwding mechanism file must
* return to public directory
*/
if (chkpub(file2)==FAIL) {
fprintf(stderr,"file must be returned to a public spool directory - uucp failed\n");
cleanup(-8);
}
}
else
if (chkpub(file2) == FAIL) {
fprintf(stderr,"\nforwarding to nonpublic directory not permitted - uucp failed\n");
cleanup(-9);
}
/*
* execute uux
* remote uucp
*/
if (Ename[0] != '\0') {
xuux(Ename, sysfile1, file1, sysfile2, file2, "");
--argc;
argv++;
continue;
}
/*
* Form reverse order of fowarding sites
*/
*tsys2 = '\0';
strcpy(tfile1, file1);
/*
* Strip off destination file
*/
i = strrchr(tfile1, '!');
*i = '\0';
/*
* Strip off last site
*/
if ((i=strrchr(tfile1, '!')) != NULL){
*i = '\0';
/*
* Get next site
*/
while ((i=strrchr(tfile1,'!')) != NULL){
strncat(tsys2, i+1, SYSNSIZE);
strcat(tsys2, "!");
*i = '\0';
}
strcat(tsys2, tfile1);
strcat(tsys2, "!");
}
strncat(tsys2, sysfile1, SYSNSIZE);
strcat(tsys2, "!");
strcat(tsys2, Myname);
if (strncmp(sys2save, Myname, SYSNSIZE) != SAME) {
strcat(tsys2, "!");
dlogent(sys2save, "sys2save");
strcat(tsys2, sys2save);
}
sysfile2 = tsys2;
dlogent(sysfile2,"reverse sysfile2");
}else
if ((strncmp(sysfile1, Myname, SYSNSIZE) != SAME) &&
(strncmp(sysfile2, Myname, SYSNSIZE) != SAME))
/*
* both sites are remote - no forwarding
* to source file
*/
{
if (Ename[0] != '\0') {
xuux(Ename, sysfile1, file1, sysfile2,
file2, "");
--argc;
argv++;
continue;
}
if (chkpub(file2) == FAIL) {
fprintf(stderr,"\nuse -e option for remote transfer to nonpublic directories\n");
cleanup(-10);
}
sprintf(tsys2, "%s!%s", Myname, sys2save);
strcpy(sysfile2, tsys2);
dlogent(sysfile2, "reverse sys2 -no fowarding");
}
/*
* If fowarding then prepend ! to fowarding string
*/
if (strchr(file1, '!') != NULL) {
*cp = '!';
strcpy(file1, cp);
*cp = '\0';
}
if ((strncmp(sysfile1, Myname, SYSNSIZE) != SAME) && (file2[0] == '!')){
/*
* remove leading ! from file2 so that
* copy case 3 will not produce !!
*/
strcpy(tfile1, &file2[1]);
strcpy(file2, tfile1);
}
#endif
} else {
sysfile1 = Myname;
strcpy(file1, argv[1]);
}
DEBUG(4, "file1 - %s\n", file1);
if (copy(sysfile1, file1, sysfile2, file2))
errors++;
#ifdef FOWARD
strcpy(sysfile2, sys2save);
#endif
--argc;
argv++;
}
clscfile();
/*
* do not spawn daemon if -r option specified
*/
limit = ulimit(1,dummy);
if (*Ropt != '-')
if (limit < CDLIMIT) {
sprintf(msg,"ULIMIT (%ld) < CDLIMIT (%ld)",limit,
CDLIMIT);
logent(User,msg);
}
else
xuucico(Rmtname);
cleanup(errors);
}
/*
* cleanup lock files before exiting
*/
cleanup(code)
register int code;
{
void exit();
logcls();
rmlock(CNULL);
if (code < 0)
fprintf(stderr, "uucp failed completely: code %d\n", code);
if (code > 0) {
fprintf(stderr, "uucp failed partially: %d error", code);
if (code==1) fprintf(stderr," \n");
else fprintf(stderr,"s \n");
}
exit(code);
}
/*
* generate copy files
* return:
* 0 -> success
* FAIL -> failure
*/
copy(s1, f1, s2, f2)
char *s1, *f1, *s2, *f2;
{
FILE *cfp, *gtcfile();
struct stat stbuf, stbuf1;
int type, statret;
char dfile[NAMESIZE];
char file1[MAXFULLNAME], file2[MAXFULLNAME];
char *strchr(), *strcat(), *strcpy();
char *strrcpy();
char opts[100];
type = 0;
opts[0] = '\0';
strcpy(file1, f1);
strcpy(file2, f2);
if (strncmp(s1, Myname, SYSNSIZE) != SAME)
type = 1;
if (strncmp(s2, Myname, SYSNSIZE) != SAME)
type += 2;
if (type & 01)
if ((strchr(file1, '*') != NULL
|| strchr(file1, '?') != NULL
|| strchr(file1, '[') != NULL))
type = 4;
switch (type) {
case 0:
/*
* all work here
*/
DEBUG(4, "all work here %d\n", type);
/*
* check access control permissions
*/
if (ckexpf(file1))
return(FAIL);
if (ckexpf(file2))
return(FAIL);
if (stat(file1, &stbuf) != 0) {
fprintf(stderr, "can't get file status %s \n copy failed\n",
file1);
return(2);
}
statret = stat(file2, &stbuf1);
if (statret == 0
&& stbuf.st_ino == stbuf1.st_ino
&& stbuf.st_dev == stbuf1.st_dev) {
fprintf(stderr, "%s %s - same file; can't copy\n", file1, file2);
return(3);
}
if (chkpth(User, "", file1) != 0
|| chkperm(file2, strchr(Optns, 'd'))
|| chkpth(User, "", file2) != 0) {
fprintf(stderr, "permission denied\n");
cleanup(1);
}
if ((stbuf.st_mode & S_IFMT) == S_IFDIR) {
fprintf(stderr, "directory name illegal - %s\n",
file1);
return(4);
}
if ((stbuf.st_mode & ANYREAD) == 0) {
fprintf(stderr, "can't read file (%s) mode (%o)\n",
file1, stbuf.st_mode);
return(5);
}
if (statret == 0 && (stbuf1.st_mode & ANYWRITE) == 0) {
fprintf(stderr, "can't write file (%s) mode (%o)\n",
file2, stbuf1.st_mode);
return(6);
}
/*
* copy file locally
*/
xcp(file1, file2);
chmod(file2, stbuf.st_mode | 0666);
logent("WORK HERE", "DONE");
return(0);
case 1:
/*
* receive file
*/
DEBUG(4, "receive file - %d\n", type);
/*
* expand source and destination file names
* and check access permissions
*/
if (file1[0] != '~')
if (ckexpf(file1))
return(7);
if (ckexpf(file2))
return(8);
if (chkpth(User, "", file2) != 0) {
fprintf(stderr, "permission denied\n");
return(9);
}
/*
* execute uux
* remote uucp
*/
if (Ename[0] != '\0') {
xuux(Ename, s1, file1, s2, file2, opts);
return(0);
}
/*
* insert JCL in file
*/
cfp = gtcfile(s1);
fprintf(cfp, "R %s %s %s %s %s\n", file1, file2, User, Optns, Sfile);
break;
case 2:
/*
* send file
*/
if (ckexpf(file1))
return(10);
if (file2[0] != '~')
if (ckexpf(file2))
return(11);
DEBUG(4, "send file - %d\n", type);
if (chkpth(User, "", file1) != 0) {
fprintf(stderr, "permission denied %s\n", file1);
return(12);
}
if (stat(file1, &stbuf) != 0) {
fprintf(stderr, "can't get status for file %s\n", file1);
return(13);
}
if ((stbuf.st_mode & S_IFMT) == S_IFDIR) {
fprintf(stderr, "directory name illegal - %s\n",
file1);
return(14);
}
if ((stbuf.st_mode & ANYREAD) == 0) {
fprintf(stderr, "can't read file (%s) mode (%o)\n",
file1, stbuf.st_mode);
return(15);
}
if (notifopt && (strchr(Optns, 'n') == NULL))
strcat(Optns, "n");
/*
* execute uux
* remote uucp
*/
if (Ename[0] != '\0') {
if(notifopt)
sprintf(opts, "-n%s", Nuser);
xuux(Ename, s1, file1, s2, file2, opts);
return(0);
}
/*
* make a copy of file in spool directory
*/
if (Copy) {
updjb(); sprintf(dfile, "%c.%.6s%c%.1s%.4d", DATAPRE, s2, Grade, subjob, jobid);
if (xcp(file1, dfile) != 0) {
fprintf(stderr, "can't copy %s\n", file1);
return(16);
}
chmod(dfile, DFILMODE);
} else {
/*
* make a dummy D. name
* cntrl.c knows names < 6 chars are dummy D. files
*/
strcpy(dfile, "D.0");
}
/*
* insert JCL in file
*/
cfp = gtcfile(s2);
fprintf(cfp, "S %s %s %s %s %s %o %s %s\n", file1, file2,
User, Optns, dfile, stbuf.st_mode & 0777, Nuser, Sfile);
break;
case 3:
case 4:
/*
* send uucp command for execution on s1
*/
DEBUG(4, "send uucp command - %d\n", type);
if (strncmp(s2, Myname, SYSNSIZE) == SAME) {
if (ckexpf(file2))
return(17);
if (chkpth(User, "", file2) != 0) {
fprintf(stderr, "permission denied\n");
return(18);
}
}
/*
* execute uux
* remote uucp
*/
if (Ename[0] != '\0') {
xuux(Ename, s1, file1, s2, file2, opts);
return(0);
}
/*
* insert JCL in file
*/
cfp = gtcfile(s1);
fprintf(cfp, "X %s %s!%s %s %s %s\n", file1, s2, file2, User, Optns, Sfile);
break;
}
return(0);
}
/*
* check security violations - forwarding to/from nonpublic directories
* ckfile -> src/dst path
* return: 0 -> ok
* FAIL -> not ok
*/
chkpub(ckfile)
char *ckfile;
{
char *s;
register char *i;
s = (i=strrchr(ckfile,'!'))?i+1:ckfile;
/*
* Ensure forwarding to/from public spool directory
*/
if (!prefix("~/",s) && !prefix(PUBDIR,s))
return(FAIL);
/*
* Detect illegal attempts to forward though (~/../) public dir.
*/
for (i = ++s; *i != '\0'; i++)
if (*i == '/' && prefix("/../", i))
return(FAIL);
return(0);
}
/*
* execute uux for remote uucp
* ename -> remote system name to execute uucp on
* s1 -> remote system name
* f1 -> remote file name
* s2 -> remote system name
* f2 -> remote file name
* opts -> uucp options
* return:
* none
*/
xuux(ename, s1, f1, s2, f2, opts)
char *ename, *s1, *s2, *f1, *f2, *opts;
{
char cmd[200];
DEBUG(4, "Ropt(%s) ", Ropt);
DEBUG(4, "ename(%s) ", ename);
DEBUG(4, "s1(%s) ", s1);
DEBUG(4, "f1(%s) ", f1);
DEBUG(4, "s2(%s) ", s2);
DEBUG(4, "f2(%s)\n", f2);
#ifdef FOWARD
if (*f2=='!') f2++;
#endif
sprintf(cmd, "uux %s %s!uucp -C %s %s!%s \\(%s!%s\\)",
Ropt, ename, opts, s1, f1, s2, f2);
DEBUG(4, "cmd (%s)\n", cmd);
system(cmd);
return;
}
FILE *Cfp = NULL;
char Cfile[NAMESIZE];
#define NSYS 20
struct presys{
char pre_name[NAMESIZE];
char pre_id[2];
char pre_grade;
}presys[NSYS];
int nsys = 0;
struct presys *csys();
/*
* get a Cfile descriptor
* sys -> system name
* return:
* an open file descriptor
*/
FILE *
gtcfile(sys)
register char *sys;
{
static int cmdcount = 0;
register int i;
struct presys *p;
extern int errno;
char *strcpy();
/*
* a new c.file is generated each time a different
* system is referenced
*/
if((p = csys(sys, Grade)) == NULL){
if(nsys != 0){
clscfile();
}
if(cmdcount == 0){
if(prjob == JOBON)
fprintf(stdout,"uucp job %d\n", jobid);
}
updjb(); sprintf(Cfile, "%c.%.6s%c%.1s%.4d", CMDPRE, sys, Grade, subjob, jobid);
cmdcount = 1;
Cfp = fopen(Cfile, "a+");
ASSERT(Cfp != NULL, "CAN'T OPEN", Cfile, 0);
insys(sys, subjob[0], Grade);
}else
if(strcmp(presys[nsys-1].pre_name, sys) != SAME){
clscfile();
sprintf(Cfile, "%c.%.6s%c%.1s%.4d", CMDPRE, sys, Grade, p->pre_id, jobid);
Cfp = fopen(Cfile, "a+");
ASSERT(Cfp != NULL, "CAN'T OPEN", Cfile, 0);
}
return(Cfp);
}
struct presys *
csys(p, g)
register char *p, g;
{
register int i;
static int jid = 0;
if(jobid != jid){
jid = jobid;
nsys = 0;
}
for(i=0;i<nsys;i++){
if(strcmp(p,&presys[i].pre_name[0]) == SAME)
if(g == presys[i].pre_grade)
return(&presys[i]);
}
return(NULL);
}
insys(p, c, g)
register char *p;
char c;
{
strcpy(presys[nsys].pre_name, p);
presys[nsys].pre_grade = g;
presys[nsys++].pre_id[0] = c;
}
/*
* close cfile
* return:
* none
*/
clscfile()
{
if (Cfp == NULL)
return;
fclose(Cfp);
/*
chmod(Cfile, ~WFMASK & 0777);
*/
logent(Cfile, "QUE'D");
US_CRS(Cfile);
Cfp = NULL;
return;
}